package Monitors.ReentrantLock;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import static ProcessThread.util.Sleeper.sleep;

@Slf4j(topic = "c.条件变量")
public class 条件变量 {

        static ReentrantLock lock = new ReentrantLock();
        static Condition waitCigaretteQueue = lock.newCondition();
        static Condition waitbreakfastQueue = lock.newCondition();
        static volatile boolean hasCigrette = false;
        static volatile boolean hasBreakfast = false;
        public static void main(String[] args) {
            new Thread(() -> {
                try {
                    lock.lock();
                    while (!hasCigrette) {
                        try {
                            waitCigaretteQueue.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    log.debug("等到了它的烟");
                } finally {
                    lock.unlock();
                }
            }).start();
            new Thread(() -> {
                try {
                    lock.lock();
                    while (!hasBreakfast) {
                        try {
                            waitbreakfastQueue.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    log.debug("等到了它的早餐");
                } finally {
                    lock.unlock();
                }
            }).start();
            sleep(1);
            sendBreakfast();
            sleep(1);
            sendCigarette();
        }
        private static void sendCigarette() {
            lock.lock();
            try {
                log.debug("送烟来了");
                hasCigrette = true;
                waitCigaretteQueue.signal();
            } finally {
                lock.unlock();
            }
        }
        private static void sendBreakfast() {
            lock.lock();
            try {
                log.debug("送早餐来了");
                hasBreakfast = true;
                waitbreakfastQueue.signal();
            } finally {
                lock.unlock();
            }
        }

}
